package Eclass.Exam;

import ibatis.IbatisHelper;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ibatis.sqlmap.client.SqlMapClient;

public class ExamManager {
	private SqlMapClient ibatis;

	public ExamManager() {
		this.ibatis = IbatisHelper.getSqlMapInstance();
	}
	
	//================ EXAM ==========================
	public ExamModel getExamSchedule(String userId, String role, boolean update) {
		List result = null;
		ExamModel result1 = new ExamModel(); 
		
		try {
			
			Map map = new HashMap();
			map.put("userId", userId);
			
			if("trainee".equalsIgnoreCase(role)) {
				result = ibatis.queryForList("eClass.getExamSchedule", map);
			} else {
				if(update) {
					ibatis.update("eClass.updateStartHourCandidate", map);
					System.out.println("update start hour\n\n");
				}
				result = ibatis.queryForList("eClass.getTechnicalTestSchedule", map);
			}
			
			System.out.println(result.size() + " size\n\n\n");
			
			//result1 = (ExamModel)result.get(0);
			
			if(result.size() == 0) {
				//result1 = null;
			} else {
				result1 = (ExamModel)result.get(0);
			}
				
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result1;
	}
	
	
	public List getSubjectForQuestion(int examPrepId) {
		List result = null;
				
		try {
			result = ibatis.queryForList("eClass.getSubjectForQuestion", examPrepId);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public Integer getTotalQuestion(String userId, int examPrepId) {
		Integer result = 0;
				
		try {
			Map map = new HashMap();
			map.put("userId", userId);
			map.put("examPrepId", examPrepId);
			
			result = (Integer)ibatis.queryForObject("eClass.getTotalQuestion", map);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return result;
	}
	
	public boolean insertExamLog(String userId, int examPrepId, String description) {
		boolean result = true;
		//List listSubject = null;
		
		try {
			Map map = new HashMap();
			map.put("examPrepId", examPrepId);
			map.put("userId", userId);
			map.put("description", description);
			//map.put("lastNo", result);
			
			ibatis.insert("eClass.insertExamLog", map);
			
			System.out.println("\n\nResult:" + result + "\n\n");

		} catch (Exception e) {
			// TODO: handle exception
			result = false;
		}
		return result;
	}
	
	public int insertQuestionForTrainee(String userId, int examPrepId) {
		int result = 0;
		List listSubject = null;
		
		try {
			listSubject = getSubjectForQuestion(examPrepId);
			
			System.out.println("\n\n\n\n\n list: " + listSubject.size() + "\n\n\n\n\n");
			
			for(int i=0; i<listSubject.size(); i++) {
				//List result = null;
				ExamModel examModel = new ExamModel();
				examModel = (ExamModel) listSubject.get(i);
				
				System.out.println("\n\nexam_prep id: " + examPrepId + " user id: " + userId);
				System.out.println("\n\n " + i +" ==== sub : " + examModel.getSubject() + " no : " + examModel.getNoOfQuestion());
				
				Map map = new HashMap();
				map.put("classId", examModel.getSubject());
				map.put("noOfQuestion", examModel.getNoOfQuestion());
				map.put("userId", userId);
				map.put("examPrepId", examPrepId);
				//map.put("lastNo", result);
				
				ibatis.insert("eClass.insertRandomQuestionBySubject", map);
				
				System.out.println("\n\nResult:" + result + "\n\n");
				
				result += examModel.getNoOfQuestion();
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return result;
	}
	
	public int insertQuestionForCandidate(String userId, int examPrepId) {
		int result = 0;
		List listSubject = null;
		
		try {
			listSubject = getSubjectForQuestion(examPrepId);
			
			System.out.println("\n\n\n\n\n list: " + listSubject.size() + "\n\n\n\n\n");
			
			for(int i=0; i<listSubject.size(); i++) {
				//List result = null;
				ExamModel examModel = new ExamModel();
				examModel = (ExamModel) listSubject.get(i);
				
				System.out.println("\n\nexam_prep id: " + examPrepId + " user id: " + userId + " candidate");
				System.out.println("\n\n " + i +" ==== sub : " + examModel.getSubject() + " no : " + examModel.getNoOfQuestion());
				
				result += examModel.getNoOfQuestion();
				System.out.println("\n\n1 Result:" + result + "\n\n");
				
				Map map = new HashMap();
				map.put("noOfQuestion", examModel.getNoOfQuestion());
				map.put("userId", userId);
				map.put("examPrepId", examPrepId);
				//map.put("lastNo", result);
				
				ibatis.insert("eClass.insertRandomQuestionCandidate", map);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return result;
	}
	
	// insert soal per subject ke table exam (tiap trainee)
	public int generateSoal(String userId, int examPrepId, String role) {
		int result = 0;
		System.out.println("\n\n\n\nuserId " + userId + " examPrepId " + examPrepId + " role " + role + "\n\n");
		
		try {
			if("trainee".equalsIgnoreCase(role)) {
				result = insertQuestionForTrainee(userId, examPrepId);
			} else if("candidate".equalsIgnoreCase(role)) {
				result = insertQuestionForCandidate(userId, examPrepId);
			}
			
			System.out.println("result : " + result + "\n\n");
			
			Map map = new HashMap();
			map.put("userId", userId);
			map.put("examPrepId", examPrepId);
			ibatis.insert("eClass.insertRandomQuestion", map);
			
			ibatis.delete("eClass.deleteExamTemp", map);
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

	public ExamModel getQuestion(String userId, int no, int examPrepId, String role) {
		ExamModel result = new ExamModel();
		//List result2 = null;
				
		System.out.println("getQuestion : " + userId + " -- " + no + " -- " + examPrepId);
		
		try {
			Map map = new HashMap();
			map.put("userId", userId);
			map.put("no", no);
			map.put("examPrepId", examPrepId);
			map.put("role", role);
			
			System.out.println("cek 1");
			
			result = (ExamModel) ibatis.queryForObject("eClass.getQuestion", map);
			System.out.println("cek 2");
			//if(result != null) {
			try {
				System.out.println("cek 3");
				System.out.println(result);
				if(result.getQ2() == null) {
					result.setQ2("");
				}
				if(result.getQ3() == null) {
					result.setQ3("");
				}
				if(result.getQ4() == null) {
					result.setQ4("");
				}
				if(result.getQ5() == null) {
					result.setQ5("");
				}
				
				if(result.getOpt2() == null) {
					result.setOpt2("");
				}
				if(result.getOpt3() == null) {
					result.setOpt3("");
				}
				if(result.getOpt4() == null) {
					result.setOpt4("");
				}
				if(result.getOpt5() == null) {
					result.setOpt5("");
				}
				
				// concat question & option of answer
				result.setQuestion(result.getQ1() + result.getQ2() + result.getQ3() + result.getQ4() + result.getQ5());
				result.setOptionOfAnswer(result.getOpt1() + result.getOpt2() + result.getOpt3() + result.getOpt4() + result.getOpt5());
				
				//System.out.println(result.getQuestion());
			} catch (Exception e) {
				// TODO: handle exception
				result = null;
			}	
				
			//}
			
			
			//result2 = ibatis.queryForList("eClass.getQuestion", map);
			//System.out.println("12345678 getResult question : " + result2.size());
			
			//System.out.println(result.getQuestion());
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public List getUnanswerQuestion(String userId, int examPrepId) {
		List result = null;
				
		//System.out.println("getQuestion : " + userId + " -- " + examPrepId);
		
		try {
			Map map = new HashMap();
			map.put("userId", userId);
			map.put("examPrepId", examPrepId);
			
			result = ibatis.queryForList("eClass.getUnanswerQuestion", map);
			//result2 = ibatis.queryForList("eClass.getQuestion", map);
			System.out.println("\n\n\n\n12345678 getResult : " + result.size());
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public boolean updateAnswer(String userId, ExamModel examModel) {
		try {
			ibatis.startTransaction();
			
			Map map = new HashMap();
			map.put("userId", userId);
			map.put("examPrepId", examModel.getExamPrepId());
			map.put("answer", examModel.getAnswer());
			map.put("no", examModel.getNo());
			
			this.ibatis.update("eClass.updateAnswer", map);
			ibatis.commitTransaction();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			try {
				ibatis.endTransaction();
			} catch (Exception e2) {
				// TODO: handle exception
				e2.printStackTrace();
			}
		}
		return true;
	}
	
	public List getAnswer(String userId, int examPrepId) {
		List result = null;
		
		//System.out.println("getQuestion : " + userId + " -- " + examPrepId);
		
		try {
			Map map = new HashMap();
			map.put("userId", userId);
			map.put("examPrepId", examPrepId);
			
			result = ibatis.queryForList("eClass.getAnswer", map);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return result;
	}
	
	public Double calculateScore(String userId, int examPrepId) {
		List result = getAnswer(userId, examPrepId);
		Double score = 0.0;
		Double tampScore = 0.0;
		int trueAnswer = 0;
		//int falseAnswer = 0;
		
		try {
			for (int i = 0; i < result.size(); i++) {
				ExamModel examModel = new ExamModel();
				examModel = (ExamModel) result.get(i);
				
				//System.out.println("i = " + i + " \n\n");
				
				tampScore = 0.0;
				trueAnswer = 0;
				//falseAnswer = 0;
				
				//System.out.println("score dr database : " + examModel.getScore() + "\n\n");

				if(examModel.getScore() == 0.0) {
					if(examModel.getAnswer() != null) {
						String[] answer = examModel.getAnswer().split("@");
						String[] keyAnswer = examModel.getKeyAnswer().split("@");
						
						// mencocokkan jawaban dengan kunci
						for (int j = 0; j < answer.length; j++) {
							for (int j2 = 0; j2 < keyAnswer.length; j2++) {
								System.out.println(answer[j] + " " + keyAnswer[j2] + "\n\n");
								if (answer[j].equals(keyAnswer[j2])) {
									//System.out.println(answer[j] + " benar\n\n");
									
									trueAnswer += 1;
									//tampScore += 100.0;
									//System.out.println("tamp score : " + tampScore + "\n\n");
								}
							}
						}
						
						// disetarain nilainya(1 no nilainya maks 100), ditambah dengan score awal
					//	System.out.println("jawaban bnr " + trueAnswer + " " + keyAnswer.length + "\n\n");
						tampScore = 100.0 * trueAnswer / keyAnswer.length;
					//	System.out.println("tamp score " + i + ": " + tampScore + "\n\n");
						
						//pengurangan score
						if(answer.length > keyAnswer.length) {
							tampScore = tampScore - ((answer.length - keyAnswer.length) * 20);
							
						//	System.out.println("nilainya dikurangin");
						//	System.out.println("score (setelah dikurangin) " + i + ": " + tampScore + "\n\n");
						}
						
						//kalau nilai minus,,nilai diset jadi 0
						if(tampScore < 0 ) {
							tampScore = 0.0;
						}
						
						score += tampScore;
					}
				} else {
					score += examModel.getScore();
					
				//	System.out.println("\nBenar\n\n");
				}
				
			//	System.out.println("tamp score akhir " + i + ": " + tampScore + "\n\n");
			}
			
			//kalau nilai minus,,nilai diset jadi 0
			if(score < 0 ) {
				score = 0.0;
			}
			//System.out.println("score (akhir) : " + score + "\n\n");
			if(score != 0.0) {
				score = score / result.size();
			} else {
				score = 0.0;
			}
			
			//System.out.println("score (akhir1) : " + score + "\n\n");
			
				
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		return score;
	}
	
	//insert nilai exam for trainee / candidate
	public boolean insertExamScore(int batchClassId, Double score, String userId, String role) {
		try {
			System.out.println(batchClassId + " " + score + " " + userId + "\n\n");
			
			Map map = new HashMap();
			map.put("batchClassId", batchClassId);
			map.put("score", score);
			map.put("userId", userId);
			
			if("trainee".equalsIgnoreCase(role)) {
				ibatis.insert("eClass.insertExamScoreForTrainee", map);
			} else if("candidate".equalsIgnoreCase(role)) {
				ibatis.insert("eClass.updateTechnicalTestScore", map);
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return true;
	}
	
}
